import socketserver
import os
from myProtocol import MyProtocol, receive_full_data


class MyTCPHandler(socketserver.BaseRequestHandler):

    def handle(self):
        while True:
            try:
                total_received_data = receive_full_data(self.request, MyProtocol.header_size)
                # 使用完整的数据解析协议
                protocol_data = MyProtocol.decode(total_received_data)
                if protocol_data == 0:
                    print('协议有误或者数据传输出现了问题，请重试')
                    error_message = MyProtocol.create_completion_message(message_code=0)
                    self.request.sendall(error_message)
                    break
                print(f'接收到的:{protocol_data}')
                action = MyProtocol.methods.get(protocol_data.method)
                if action == 'upload':
                    print("客户端执行上传操作")
                    if not os.path.exists('lists'):
                        os.makedirs('lists')

                    filename = os.path.join('lists', protocol_data.filename)
                    with open(filename, 'wb') as f:
                        f.write(protocol_data.data)

                    print(f'File {filename} uploaded successfully.')
                    # 发送完成消息
                    completion_message = MyProtocol.create_completion_message(message_code=1)
                    self.request.sendall(completion_message)
                    print('--------------------------')

                if action == 'download':
                    print("客户端执行下载操作")
                    filename = os.path.join('lists', protocol_data.filename)
                    # 不存在对应文件
                    if not os.path.isfile(filename):
                        completion_message = MyProtocol.create_completion_message(message_code=0)
                        self.request.sendall(completion_message)
                        print(f'File {filename}  download not exists .')
                    else:
                        # 读取文件内容
                        with open(filename, 'rb') as f:
                            file_data = f.read()

                        print(f'File {filename}  download exists .')
                        # 创建 MyProtocol 实例
                        protocol = MyProtocol(
                            version=2,
                            magic=0x1234,
                            method='download',
                            filename=filename,
                            data=file_data
                        )
                        # 编码并发送数据
                        print(f'发送：{protocol}')
                        encoded_data = protocol.encode()
                        self.request.sendall(encoded_data)

                    print('--------------------------')
                if action == 'show':
                    print("客户端请求显示文件列表")
                    directory = 'lists'
                    try:
                        # 获取文件列表，这里只列出文件，过滤掉目录
                        files = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))]
                        # 将文件列表转换为字符串，每个文件名后跟一个换行符
                        file_list_str = '\n'.join(files)
                        # 创建 MyProtocol 实例
                        protocol = MyProtocol(
                            version=2,
                            magic=0x1234,
                            method='show',
                            filename='',  # 文件名字段可以为空
                            data=file_list_str.encode('utf-8')  # 将字符串编码为字节
                        )
                        # 编码并发送数据
                        encoded_data = protocol.encode()
                        print(f'发送：{protocol}')
                        self.request.sendall(encoded_data)
                        print('--------------------------')
                    except Exception as e:
                        print(f"错误：无法获取文件列表。{e}")
                        # 发送错误信息
                        error_message = MyProtocol.create_completion_message(message_code=0)
                        self.request.sendall(error_message)

                # ... 处理其他操作 ...

            except ConnectionResetError as e:
                print('Connection error:', e)
                break
            except IOError as e:
                print('File IO error:', e)
                break


if __name__ == '__main__':
    HOST, POST = 'localhost', 9999
    # 实例化TCPServer
    server = socketserver.ThreadingTCPServer((HOST, POST), MyTCPHandler)  # ThreadingTCPServer：多线程，多个客户端可以请求
    # 这样此服务器就可以让多个客户端连接
    # 处理多个请求
    server.serve_forever()
